package com.aisino.springai.demos.chat.controller;

import com.alibaba.fastjson.JSONObject;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;

/**
 * @author guochuantao
 * @version 1.0
 * @description
 * @since 2025/4/2 上午11:33
 */
@RestController
@RequestMapping("/chat")
@CrossOrigin
public class DefaultSettingsChatController {
    private final ChatClient chatClient;

    public DefaultSettingsChatController(ChatClient.Builder chatClient) {
        this.chatClient = chatClient
                .defaultSystem("你是一个{role}，请根据用户提问回答！") // 模板动态修改系统模型角色
                .defaultAdvisors(
                        // 实现 Chat Memory 的 Advisor 在使用 Chat Memory 时，需要指定对话 ID，以便 Spring AI 处理上下文。
                        new MessageChatMemoryAdvisor(new InMemoryChatMemory())
                )
                .build();
    }

    /**
     * {
     * "message":"你好",
     * "role":"博学多实的温柔可爱的小女生，名字叫璇璇"
     * }
     * ========如果参数是上面的，输出的结果就是下面的否则就是默认女助手。========
     * 你好呀~我是璇璇！今天天气真好，阳光暖暖的，让人心情特别愉快呢。你有什么想和我聊的吗？我很期待和你成为好朋友哦！
     */
    @GetMapping("/default")
    public String chat(@RequestBody JSONObject param) {
        String roleInfo = param.getString("role") != null ? param.getString("role") : "博学的甜美可爱的智能聊天女助手";
        String message = param.getString("message");
        return chatClient.prompt()
                .system(role -> role.param("role", roleInfo))
                .user(message)
                .call()
                //.stream() // 流式返回数据结果
                .content();
    }

    /**
     * ChatClient 使用自定义的 Advisor 实现功能增强.  [[必须指定同一个 Conversation ID]]
     * eg:
     * http://127.0.0.1:8080/chat/advisor/123?message=你好，我叫苓茜，之后的会话中都带上我的名字
     * 好的，苓茜，很高兴认识你！在之后的会话中，我都会带上你的名字，有什么问题或需要聊的话题吗？苓茜。
     * http://127.0.0.1:8080/chat/advisor/123?message=我叫什么名字？
     * 你叫苓茜呀。有什么事情想要分享或者讨论吗，苓茜？
     */
    @GetMapping("/advisor/{id}")
    public Flux<String> advisorChat(
            HttpServletResponse response,
            @PathVariable("id") String id,// Conversation ID
            @RequestParam("message") String message) {
        response.setCharacterEncoding("UTF-8");
        return this.chatClient.prompt(message)
                .advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, id)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
                .stream().content();
    }
}
